package utilitarios;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Formato {

    private SimpleDateFormat formato;
    private SimpleDateFormat formatoHora;
    
    public Formato(){
        formato = new SimpleDateFormat("dd/MM/yyyy");
        formato.setLenient(false);
        formatoHora = new SimpleDateFormat("HH:mm");
        formatoHora.setLenient(false);
    }
    

    
    /**
     * Utilizado para validar se o campo esta vazio ou nulo.
     * @param campo Campo a se validado.
     * @return True se o campo estiver vazio e senão False.
     **/
    protected boolean estaVazio(String campo) {
        if (campo == null || campo.trim().equals("")) {
            return true;
        } else {
            return false;
        }
    }
    
    /**
     * Utilizado para validar se o campo é um codigo numerico valido.
     * @param campo Campo a se validado.
     * @return True se o campo contiver apenas numeros senão False.
     **/
    protected boolean numeroValido(String campo) {
        try {
           Long.parseLong(campo.toString());
           return true;
        } catch (Exception e) {
           return false;
        }
    }
    
    /**
     * Utilizado para validar se o campo o uma data valida (DD/MM/YYYY)
     * @param campo Campo a se validado.
     * @return True se o campo for valido senão False.
     **/
    protected boolean dataValida(String campo) {
        try {
            formato.parse(campo);
            return true;
        } catch (ParseException ex) {
            return false;
        }
    }

    /**
     * Utilizado para validar se o campo é uma hora HH:MM
     * @param campo Campo a se validado.
     * @return True se o campo for valido senão False.
     **/
    protected boolean horaValida(String campo) {
        try {
            formatoHora.parse(campo);
            return true;
        } catch (ParseException ex) {
            return false;
        }
    }
    
    /**
     * Utilizado para validar se o campo possui o tamanho especificado pelo parametro
     * @param campo Campo a se validado.
     * @return True se o campo for valido senão False.
     **/
    protected boolean tamanhoValido(String campo, int tamanho) {        
        if (campo.length() == tamanho) {
            return true;
        } else {
            return false;
        }
    }
      
    /**
     * Utilizado para validar se o campo possui o tamanho especificado pelo parametro,
     * neste caso o campo não pode ter o tamanho superior ao especificado
     * @param campo Campo a se validado.
     * @return True se o campo for valido senão False.
     **/
    protected boolean tamanhoCampo(String campo, int tamanho) {        
        if (campo.length() <= tamanho) {
            return true;
        } else {
            return false;
        }
    }
    
    /** Utilizado para validar campos com valores monetarios */
    protected boolean validarDinheiro(String value) {
        String valor = value.toString().replace(",",".");
        try {
            Double.parseDouble(valor);
            return true;
        } catch (Exception ex) {
            return false;
        }        
    }    
    
    /** Utilizado para formatar numero */
	protected String formataValor(String valor) {
		BigDecimal bd = new BigDecimal(valor);
		
		bd.setScale(8, BigDecimal.ROUND_HALF_UP);
		
		String pattern = "###,###,##0.00";
		
		Locale locale = new Locale("pt", "BR");
		
		DecimalFormatSymbols symbols = new DecimalFormatSymbols(locale);
		
		symbols.setDecimalSeparator(',');
		symbols.setGroupingSeparator('.');
		
		DecimalFormat f = new DecimalFormat(pattern, symbols);
		return f.format(bd);
	}

	
    /** Utilizado para formatar Nota e Falta */
	protected String formataNota(String valor) {
		BigDecimal bd = new BigDecimal(valor);
		bd.setScale(8, BigDecimal.ROUND_HALF_UP);
		String pattern = "###00";
		DecimalFormat f = new DecimalFormat(pattern);
		return f.format(bd);
	}

    /**
	 * Utilizado para validar se um campo contem um valor valido, definido como
	 * campo tinyint.
	 * 
	 * @param campo
	 *            Campo do modelo a ser validado.
	 * @param valores
	 *            Coleção de valores validos. return True se o campo possuir um
	 *            valor definido na coleçào de valores. Senão false.
	 */
    protected boolean validarTinyintValidos(String campo, int ... valores) {
        try {
            int vl = Integer.parseInt(campo);
            for (int item : valores) {
                if (vl == item) {
                    return true;
                }
            }
            return false;
        } catch (Exception e) {
            return false;
        } 
    }

      /* Metodo pra validar Email*/

    protected boolean validaEmail(String email) {
        Pattern p = Pattern.compile("^[\\w-]+(\\.[\\w-]+)*@([\\w-]+\\.)+[a-zA-Z]{2,7}$");
        Matcher m = p.matcher(email);
        if (m.find()) {
            return true;
        }
        return false;
    }

    protected boolean valida_CpfCnpj(String s_aux) {
//------- Rotina para CPF
        if (s_aux.length() == 11) {
            int d1, d2;
            int digito1, digito2, resto;
            int digitoCPF;
            String nDigResult;
            d1 = d2 = 0;
            digito1 = digito2 = resto = 0;
            for (int n_Count = 1; n_Count < s_aux.length() - 1; n_Count++) {
                digitoCPF = Integer.valueOf(s_aux.substring(n_Count - 1, n_Count)).intValue();
//--------- Multiplique a ultima casa por 2 a seguinte por 3 a seguinte por 4 e assim por diante.
                d1 = d1 + (11 - n_Count) * digitoCPF;
//--------- Para o segundo digito repita o procedimento incluindo o primeiro digito calculado no passo anterior.
                d2 = d2 + (12 - n_Count) * digitoCPF;
            }
            ;
//--------- Primeiro resto da divisão por 11.
            resto = (d1 % 11);
//--------- Se o resultado for 0 ou 1 o digito é 0 caso contrário o digito é 11 menos o resultado anterior.
            if (resto < 2) {
                digito1 = 0;
            } else {
                digito1 = 11 - resto;
            }
            d2 += 2 * digito1;
//--------- Segundo resto da divisão por 11.
            resto = (d2 % 11);
//--------- Se o resultado for 0 ou 1 o digito é 0 caso contrário o digito é 11 menos o resultado anterior.
            if (resto < 2) {
                digito2 = 0;
            } else {
                digito2 = 11 - resto;
            }
//--------- Digito verificador do CPF que está sendo validado.
            String nDigVerific = s_aux.substring(s_aux.length() - 2, s_aux.length());
//--------- Concatenando o primeiro resto com o segundo.
            nDigResult = String.valueOf(digito1) + String.valueOf(digito2);
//--------- Comparar o digito verificador do cpf com o primeiro resto + o segundo resto.
            return nDigVerific.equals(nDigResult);
        } //-------- Rotina para CNPJ
        else if (s_aux.length() == 14) {
            int soma = 0, aux, dig;
            String cnpj_calc = s_aux.substring(0, 12);
            char[] chr_cnpj = s_aux.toCharArray();
//--------- Primeira parte
            for (int i = 0; i < 4; i++) {
                if (chr_cnpj[i] - 48 >= 0 && chr_cnpj[i] - 48 <= 9) {
                    soma += (chr_cnpj[i] - 48) * (6 - (i + 1));
                }
            }
            for (int i = 0; i < 8; i++) {
                if (chr_cnpj[i + 4] - 48 >= 0 && chr_cnpj[i + 4] - 48 <= 9) {
                    soma += (chr_cnpj[i + 4] - 48) * (10 - (i + 1));
                }
            }
            dig = 11 - (soma % 11);
            cnpj_calc += (dig == 10 || dig == 11)
                    ? "0" : Integer.toString(dig);
//--------- Segunda parte
            soma = 0;
            for (int i = 0; i < 5; i++) {
                if (chr_cnpj[i] - 48 >= 0 && chr_cnpj[i] - 48 <= 9) {
                    soma += (chr_cnpj[i] - 48) * (7 - (i + 1));
                }
            }
            for (int i = 0; i < 8; i++) {
                if (chr_cnpj[i + 5] - 48 >= 0 && chr_cnpj[i + 5] - 48 <= 9) {
                    soma += (chr_cnpj[i + 5] - 48) * (10 - (i + 1));
                }
            }
            dig = 11 - (soma % 11);
            cnpj_calc += (dig == 10 || dig == 11)
                    ? "0" : Integer.toString(dig);
            return s_aux.equals(cnpj_calc);
        } else {
            return false;
        }
    }
    
    
    /** 
     * Utilizado para transformar o estado do objeto em letras maiusculas.
     * OBS - Todos os campos do objeto devem ser do tipo String.
     **/
    protected final void atributosParaMaisculo() {
        Field[] campos = this.getClass().getDeclaredFields();
        for (Field cp : campos) {
            String get  = cp.getName().substring(0,1).toUpperCase();
            get += cp.getName().substring(1,cp.getName().length());
            get = "get"+get;
            String set  = cp.getName().substring(0,1).toUpperCase();
            set += cp.getName().substring(1,cp.getName().length());
            set = "set"+set;
            try {
                Method getCampo = this.getClass().getMethod(get);
                Object valor = getCampo.invoke(this);
                if (valor == null) {
                    continue;
                }
                Method setCampo = this.getClass().getMethod(set,String.class);
                setCampo.invoke(this,valor.toString().toUpperCase());
            } catch (Exception ex) {
                //ex.printStackTrace();
                continue;
            }
        }
    }
    
    /**
     * Transforma o formato de data convecional DD/MM/AAAA para o formato
     * gravado no MySQL AAAA-MM-DD.
     * @param str Data no formato comum.
     * @return Campo com a data no formato de gravação MySql.
     */
    protected final String dataForMySqlData(final String str) {
        if(str != null){
        	if(!str.equals("")){
        		if (str.length() == 10) {
        			String data = str;
        			String dia = data.substring(0,2);
        			String mes = data.substring(3,5);
        			String ano = data.substring(6,data.length());
        			return (ano+"-"+mes+"-"+dia);
        		} else {
        			return str;
        		}
        	}else {
        		return str;
        	}
        }else {
        	return str;
        }
    }
    
    /**
     * Transforma o formato de data do MySql AAAA-MM-DD para o formato
     * tradicional DD/MM/YYYY
     * @param str Data no formato comum.
     * @return Campo com a data no formato de gravação MySql.
     */
    protected final String mySqlDataForData(final String str) {
       if(str != null){
       	if(!str.equals("")){
        	if (str.length() == 10){
                String data = str;
                String ano = data.substring(0,4);
                String mes = data.substring(5,7);
                String dia = data.substring(8,10);
                return (dia+"/"+mes+"/"+ano);
            } else {
                return str;
            }
        }else
        	return str;
       }else {
    	   return str;
       }
    }


}
